import { defineStore } from 'pinia'
import aesHelper from '@/utils/aesHelper'
import { login } from '@/utils/mpHelper'
import store from '@/store'
import { useGlobalStore } from './global'
import { getOpenId } from '@/api/account'
import { decryptPhone, getPhoneToken } from '@/api/account'
import { useApplianceStore } from './appliance'
import netconfig from '@/config/netconfig'
import { popRequestQueue } from '@/utils/request'

export type State = {
  /**
   * Encrypted
   */
  openid: string
  unionid: string
  token: string
  ciamId: string
  key: string
  iv: string
  /**
   * Decrypted
   */
  accessToken: string
  accessOpenId: string
  accessUnionId: string
  accessPhoneNumber: string
  /**
   * Statement
   */
  needRefreshToken: boolean
  loginRefresh: boolean
}
export type Getters = {
  isLogin(state: State): boolean
}
export type Actions = {
  initStoredData(): void
  loadOpenAndUnionId(): Promise<void>
  loadOpenIdAndSessionKey(): Promise<void>
  // loadDecryptedPhone(): Promise<void>
  loadPhoneToken(): Promise<void>
  removeAllUserInfo(): Promise<void>
  removePartialUserInfo(): Promise<void>
  updateToken(token: string): void
}

export const useAuthStore = defineStore<'auth', State, Getters, Actions>('auth', {
  state: () => ({
    /**
     * Encrypted
     */
    openid: '',
    unionid: '',
    token: '',
    ciamId: '',
    key: '',
    iv: '',
    /**
     * Decrypted
     */
    accessToken: '',
    accessOpenId: '',
    accessUnionId: '',
    accessPhoneNumber: '',
    /**
     * Statement
     */
    needRefreshToken: true, // 是否需要刷新token
    loginRefresh: false, // 是否更新过token
  }),
  getters: {
    isLogin: ({ accessToken }) => !!accessToken,
  },
  actions: {
    initStoredData() {
      let key = uni.getStorageSync('cache_key')
      let iv = uni.getStorageSync('cache_iv')

      if (!key || !iv) {
        uni.removeStorageSync('openid')
        uni.removeStorageSync('ciamId')
        uni.removeStorageSync('token')
        uni.removeStorageSync('unionid')
        const buffer_key = new Uint8Array(32)
        const buffer_iv = new Uint8Array(32)
        for (let i = 0; i < 32; i++) {
          buffer_key[i] = Math.floor(Math.random() * 255)
          buffer_iv[i] = Math.floor(Math.random() * 255)
        }

        key = Array.from(new Uint8Array(buffer_key))
          .map((x) => ('00' + x.toString(16)).slice(-2))
          .join('')
        uni.setStorageSync('cache_key', key)

        iv = Array.from(new Uint8Array(buffer_iv))
          .map((x) => ('00' + x.toString(16)).slice(-2))
          .join('')
        uni.setStorageSync('cache_iv', iv)
      } else {
        this.ciamId = uni.getStorageSync('ciamId')
        this.accessToken = aesHelper.decrypt(uni.getStorageSync('token'), key, iv)
        this.accessPhoneNumber = aesHelper.decrypt(this.ciamId, key, iv)
      }
      this.key = key
      this.iv = iv
    },
    /**
     * 获取openid(刷新token的入参需要openid)
     */
    async loadOpenAndUnionId(): Promise<void> {
      const openIdStorage = uni.getStorageSync('openid')
      const unionIdStorage = uni.getStorageSync('unionid')
      if (openIdStorage && unionIdStorage) {
        this.accessOpenId = aesHelper.decrypt(openIdStorage, this.key, this.iv)
        this.accessUnionId = aesHelper.decrypt(unionIdStorage, this.key, this.iv)
        if (this.accessUnionId && this.accessOpenId) {
          return Promise.resolve()
        }
      }
      await this.loadOpenIdAndSessionKey()
      return Promise.resolve()
    },
    async loadOpenIdAndSessionKey(): Promise<void> {
      try {
        const result = await login()

        // 用d.code换取openid
        const res = await getOpenId(result.code)
        const { openid: accessOpenId, unionid: accessUnionId } = res.data
        this.accessOpenId = accessOpenId
        this.openid = aesHelper.encrypt(accessOpenId, this.key, this.iv)
        uni.setStorageSync('openid', this.openid)

        this.accessUnionId = accessUnionId
        this.unionid = aesHelper.encrypt(accessUnionId, this.key, this.iv)
        uni.setStorageSync('unionid', this.unionid)
      } catch (e) {
        console.error('loadOpenIdAndSessionKey', e)
        return Promise.reject(e)
      }
    },

    /**
     * 获取HCMP小程序带过来的加密手机号
     */
    // async loadDecryptedPhone() {
    //   const globalStore = useGlobalStore(store)
    //   let accessPhoneNumber = ''

    //   try {
    //     const res = await decryptPhone()
    //     accessPhoneNumber = res.data.slice(3)
    //   } catch (e) {
    //     console.error(e)
    //     if (this.ciamId) {
    //       accessPhoneNumber = aesHelper.decrypt(this.ciamId, this.key, this.iv)
    //     }
    //   } finally {
    //     globalStore.launchOptions = null
    //     this.ciamId = aesHelper.encrypt(accessPhoneNumber, this.key, this.iv)
    //     this.accessPhoneNumber = accessPhoneNumber
    //   }
    // },
    // 刷新Token
    async loadPhoneToken() {
      try {
        console.log('loadPhoneToken', this.accessPhoneNumber)
        await this.loadOpenAndUnionId()
        await getPhoneToken({
          loginid: this.accessPhoneNumber,
          unionid: this.accessUnionId,
          openid: this.accessOpenId,
          type: netconfig.MINI_TYPE,
          env: netconfig.PLUGIN_ENV,
        }).then((res: any) => {
          if (res.data.code == 1000) {
            wx.navigateTo({
              url: 'plugin://hello-plugin/homeconnecLogin?isFromOmp=false&hasPhoneNo=true',
            })
            wx.removeStorageSync('ciamId')
            wx.removeStorageSync('token')
            this.updateToken('')
          } else if (res.data.code == 2000) {
            // 最新的token获取成功
            const accessToken = res.data.data.token
            this.updateToken(accessToken)
          } else if (res.data.code == 500001) {
            this.updateToken(this.accessToken)
          } else {
            wx.removeStorageSync('ciamId')
            wx.removeStorageSync('token')
            this.updateToken('')
          }
        })
      } catch (e) {
        console.error('updateToken', e)
        this.updateToken('')
      }
    },
    updateToken(token) {
      this.accessToken = token
      uni.setStorageSync('token', aesHelper.encrypt(token, this.key, this.iv))
      // uni.setStorageSync('expires_time', new Date().getTime())
      // 延迟触发请求队列回调 防止阻塞请求
      setTimeout(() => popRequestQueue())
    },
    //删除所有关于用户的缓存信息
    async removeAllUserInfo() {
      const applianceStore = useApplianceStore()
      try {
        this.accessToken = ''
        applianceStore.list = []
        applianceStore.currentHaId = ''
        // this.recommend = ''
        // this.shareId = ''
        uni.removeStorageSync('token')
        uni.removeStorageSync('signInfo')
        uni.removeStorageSync('applianceList')
        uni.removeStorageSync('fridgeFlexModes')
        uni.removeStorageSync('userProfile')
        uni.removeStorageSync('expires_time')
        uni.removeStorageSync('ciamId')
      } catch (error) {}
    },
    //删除所有关于用户的缓存信息
    async removePartialUserInfo() {
      const applianceStore = useApplianceStore()
      try {
        this.accessToken = ''
        applianceStore.list = []
        applianceStore.currentHaId = ''
        // this.recommend = ''
        // this.shareId = ''
        uni.removeStorageSync('token')
        uni.removeStorageSync('signInfo')
        uni.removeStorageSync('applianceList')
        uni.removeStorageSync('fridgeFlexModes')
        // uni.removeStorageSync('userProfile')
      } catch (error) {}
    },
  },
})
